﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

using King.Declarative;
using King.Text;
using King.Xml.CSharp;
using King.Rest.Xml.CSharp;

namespace King.Atom {

    [XsSchema(Namespace)]
    public class atom {
        public const string Namespace = "http://www.w3.org/2005/Atom";
        public readonly XNamespace XNamespace = (XNamespace)Namespace;

        [XsSimpleType(AliasFor = typeof(string))]
        public class String : Xs.String { }

        [RestXmlComplexType]
        public class Author {

            [RestXmlProperty(1)]
            public string Name;
        }

        [RestXmlComplexType]
        public class Entry {

            [RestXmlProperty(1)]
            public string Title;

            [RestXmlProperty(2)]
            public string Updated;

            [RestXmlProperty(3)]
            public Author Author;

            [RestXmlProperty(4)]
            public int Id;

            [RestXmlProperty(5)]
            public string Content;
        }
    }

    public class AtomXml : TextDeclaration {

        private const string DataServicesNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
        private const string DataServicesMetadataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
        private const string AtomNamespace = "http://www.w3.org/2005/Atom";

        private static readonly XNamespace D = (XNamespace)DataServicesNamespace;
        private static readonly XNamespace M = (XNamespace)DataServicesMetadataNamespace;
        private static readonly XNamespace A = (XNamespace)AtomNamespace;

        private Dictionary<string, object> m_arguments;

        public AtomXml(Dictionary<string, object> arguments) {
            m_arguments = arguments;
        }

        protected override IEnumerable Children(DeclarationContext frame) {

            // boilerplate ATOM envelope
            var xml = new XElement(A + "entry",
                new XAttribute(XNamespace.Xmlns + "d", DataServicesNamespace),
                new XAttribute(XNamespace.Xmlns + "m", DataServicesMetadataNamespace),

                new XElement(A + "title"),
                new XElement(A + "updated", DateTime.UtcNow),

                new XElement(A + "author",
                    new XElement(A + "name")
                ), new XElement(A + "id"),

                new XElement(A + "content",
                    new XAttribute("type", "application/xml"),
                    new XElement(M + "properties",
                        from o in m_arguments
                        orderby o.Key
                        select new XElement(D + o.Key, o.Value)
                    )
                )
            );

            return new TextSingleSpaced {
                    "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>",
                    xml.ToString()
                };
        }
    }
}
